<?php

namespace App\Biz;

use App\Exceptions\TokenExpiredException;
use Exception;
use Illuminate\Http\Client\Response;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Http;
use Symfony\Component\HttpFoundation\File\UploadedFile;

class HttpBiz
{
    protected string $apiUrl = "http://visitor.cmbl.com.cn/ai/vesionbook-building-core/api/v1/";

    protected array $headers = [
        'Accept-Encoding' => 'gzip, deflate',
        'Accept-Language' => "zh-CN,zh;q=0.9",
        'Connection'      => 'keep-alive',
        'Content-Type'    => 'application/json;',
        'Accept'          => 'application/json, text/plain, */*',
        'Host'            => 'visitor.cmbl.com.cn',
        'Origin'          => "http://visitor.cmbl.com.cn",
        'Referer'         => "http://visitor.cmbl.com.cn/801/visitor/apply?openid=owxLQwpziJnmRWYWzE4-H5CT--28",
        'User-Agent'      => "Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.3 (KHTML, like Gecko) Version/10.0 Mobile/14E304 Safari/602.1 wechatdevtools/1.06.2209190 MicroMessenger/8.0.5 Language/zh_CN webview/16723623051445914 webdebugger port/46291 token/62c9f07b0ae4b7a2169457a1b7149b8f"
    ];

    /**
     * @return array
     */
    public function getHeaders(): array
    {
        return $this->headers;
    }

    /**
     * 发送POST请求
     * @param string $token
     * @param string $endpoint
     * @param array $data
     * @return Collection
     * @throws TokenExpiredException
     */
    private function post(string $token, string $endpoint, array $data = []): Collection
    {
        $headers          = $this->headers;
        $headers['token'] = " Bearer {$token}";
        $response         = Http::withHeaders($headers)
            ->post("{$this->apiUrl}{$endpoint}", $data);
        return $this->responseValidate($response);
    }

    /**
     * 受访者登录
     * @param int $authorId
     * @param string $openId
     * @param string $phone
     * @return Collection
     * @throws TokenExpiredException
     */
    public function intervieweeLogin(int $authorId, string $openId, string $phone): Collection
    {
        return $this->post('', "/visitor/h5/login", [
            "authorId"  => $authorId,
            "openId"    => $openId,
            "telephone" => $phone
        ]);
    }

    /**
     * 接口返回数据验证
     * @param Response $response
     * @return Collection
     * @throws TokenExpiredException
     * @throws Exception
     */
    public function responseValidate(Response $response): Collection
    {
        if ($response->failed()) {
            throw new Exception("接口状态错误 {$response->status()}");
        }
        if ($response->offsetGet('respCode') == 14000006) {
            throw new TokenExpiredException($response->offsetGet('respMessage'));
        }
        if ($response->offsetGet('respCode') != 10000000) {
            throw new Exception($response->offsetGet('respMessage'));
        }
        return collect($response->offsetGet('data'));
    }

    /**
     * 提交访客预约
     * @param array $data
     * @return Collection
     * @throws TokenExpiredException
     */
    public function submitVisitorReserves(array $data): Collection
    {
        return $this->post('', "/visitor/h5/apply", $data);
    }

    /**
     * 访客预约列表
     * @param string $token
     * @return Collection
     * @throws TokenExpiredException
     */
    public function visitorReservesList(string $token): Collection
    {
        return $this->post($token, "/visitor/h5/list", ['listType' => 1]);
    }

    /**
     * 访客预约审核
     * @param string $token
     * @param string $appId
     * @param string $uniqueIds
     * @param int $verifyStatus
     * @return Collection
     * @throws TokenExpiredException
     */
    public function visitorReservesApproval(string $token, string $appId, string $uniqueIds, int $verifyStatus = 1): Collection
    {
        return $this->post($token, "/visitor/h5/approval", [
            'appId'        => $appId,
            'remark'       => null,
            'uniqueIds'    => $uniqueIds,
            'verifyStatus' => $verifyStatus,
        ]);
    }

    /**
     * 文件上传
     * @param UploadedFile $file
     * @return Collection
     * @throws TokenExpiredException
     */
    public function imageUpload(UploadedFile $file): Collection
    {
        // The imageUpload method does not seem to use a token in the headers, so we leave it as is.
        $response = Http::attach(
            'file', $file->getContent(), $file->getClientOriginalName()
        )->post("{$this->apiUrl}/common/image/upload");

        return $this->responseValidate($response);
    }

    /**
     * 获取图片
     * @param string $rul
     * @return Response
     */
    public function image(string $rul): Response
    {
        // The image method does not seem to use a token in the headers, so we leave it as is.
        return Http::get($rul);
    }
}
